package ru.inse.core.domain.realty;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


/**
 * Объект недвижимоти
 * @author evga
 *
 */
public class RealtyObject
{
    static final private Map<Long, RealtyObject> mapById = new LinkedHashMap<Long, RealtyObject>();
    static final private Map<RealtyObjectType, List<RealtyObject>> mapByType = new LinkedHashMap<RealtyObjectType, List<RealtyObject>>();
    static private RealtyObject [] array;
    
    //Посуточное
    static final public RealtyObject DAILY_FLAT = new RealtyObject(100L, RealtyObjectType.DAILY_HOUR, "realty.object.lease_flat"); //Посуточно
    static final public RealtyObject DAILY_HOTEL = new RealtyObject(101L, RealtyObjectType.DAILY_HOUR, "realty.object.lease_hotel"); //Посуточно
//    static final public RealtyObject DAILY_SAUNA = new RealtyObject(102L, RealtyObjectType.DAILY_HOUR, "realty.object.lease_sauna"); //Бани/Сауны
    //Жилая недвижимость
    static final public RealtyObject NEW = new RealtyObject(200L, RealtyObjectType.RESIDENTIAL, "realty.object.new"); //Новостроки
    static final public RealtyObject SECONDARY = new RealtyObject(201L, RealtyObjectType.RESIDENTIAL, "realty.object.secondary"); //Вторичное
    static final public RealtyObject HOUSES = new RealtyObject(202L, RealtyObjectType.RESIDENTIAL, "realty.object.houses"); //Коттеджи, дома, таунхаусы
    static final public RealtyObject GARDENS = new RealtyObject(203L, RealtyObjectType.RESIDENTIAL, "realty.object.gardens"); //Дачи, сады
    
    //Земельные участки
    static final public RealtyObject HOUSING = new RealtyObject(300L, RealtyObjectType.LAND, "realty.object.housing"); //Под индивидуальное жилищное строительство
    static final public RealtyObject AGRICULTURAL = new RealtyObject(301L, RealtyObjectType.LAND, "realty.object.agricultural"); //Сельскохозяйственного назначения
    static final public RealtyObject COMMERCIAL = new RealtyObject(302L, RealtyObjectType.LAND, "realty.object.commercial"); //Под строительство коммерческих объектов

    //Гаражи, парковки
    static final public RealtyObject COOPERATIVE = new RealtyObject(400L, RealtyObjectType.GARAGE, "realty.object.cooperative"); //Гаражные кооперативы
    static final public RealtyObject SINGLE = new RealtyObject(401L, RealtyObjectType.GARAGE, "realty.object.single"); //Отдельно стоящие гаражи
    static final public RealtyObject PARKING = new RealtyObject(402L, RealtyObjectType.GARAGE, "realty.object.parking"); //Парковки
    
    //Коммерческая недвижимость
    static final public RealtyObject OFFICE = new RealtyObject(500L, RealtyObjectType.COMMERCE, "realty.object.office"); //Офисная
    static final public RealtyObject TRADE = new RealtyObject(501L, RealtyObjectType.COMMERCE, "realty.object.trade"); //Торговая
    static final public RealtyObject PRODUCTION = new RealtyObject(502L, RealtyObjectType.COMMERCE, "realty.object.production"); //Производственная
    static final public RealtyObject WAREHOUSE = new RealtyObject(503L, RealtyObjectType.COMMERCE, "realty.object.warehouse"); //Складская
    static final public RealtyObject OTHER = new RealtyObject(504L, RealtyObjectType.COMMERCE, "realty.object.other"); //Свободного назначения

    static final public RealtyObject CHANGE = new RealtyObject(600L, RealtyObjectType.CHANGE, "realty.object.change"); //Для обмена
    
    
    
    
    final private Long id;
    final private String labelId;
    final private RealtyObjectType type;

    private RealtyObject(Long id, RealtyObjectType type, String label)
    {
        this.id = id;
        this.labelId = label;
        this.type = type;
        mapById.put(id, this);
        putByType(this, type);
        array = null;
    }

    private void putByType(RealtyObject object, RealtyObjectType type)
    {
        synchronized (mapByType)
        {
            List<RealtyObject> list = mapByType.get(type);
            if (list == null)
            {
                if (list == null)
                {
                    list = new LinkedList<RealtyObject>();
                }
            }
            if (!list.contains(object))
            {
                list = new LinkedList<RealtyObject>(list);
                list.add(object);
            }
            mapByType.put(type, Collections.unmodifiableList(list));
        }
    }

    public Long getId()
    {
        return id;
    }

    public String getLabelId()
    {
        return labelId;
    }
    
    public RealtyObjectType getObjectType()
    {
        return type;
    }

    static public List<RealtyObject> getByType(RealtyObjectType type)
    {
        List<RealtyObject> result = mapByType.get(type);
        return result != null ? result :  Collections.<RealtyObject>emptyList();
    }

    static public RealtyObject getById(Long id)
    {
        return mapById.get(id);
    }
    
    @Override
    public String toString()
    {
        return labelId;
    }
    
    static public RealtyObject getDefaultByType(RealtyObjectType type)
    {
        List<RealtyObject> result = mapByType.get(type);
        return (result == null || result.isEmpty()) ? null :  result.get(0);

    }
    
    static public RealtyObject [] list()
    {
        if (array == null)
        {
            synchronized (RealtyObject.class)
            {
                if (array == null)
                {
                    array = new RealtyObject[mapById.size()];
                    int index = 0;
                    for (RealtyObject r : mapById.values())
                    {
                        array[index++] = r;
                    }
                }
            }
        }
        return array;
    }
}
